package com.dysm.multithread;

/**
 * 哲学家就餐问题
 */
public class PhilosopherQuestionTest {
    // chopsticks
    private boolean[] used = new boolean[] { false, false, false, false, false };
    private static String LOCK = "static_class_lock";
 
    public static void main(String[] args) {
        PhilosopherQuestionTest philosopherQuestionTest = new PhilosopherQuestionTest();
        philosopherQuestionTest.new Philosopher1(0).start();
        philosopherQuestionTest.new Philosopher1(1).start();
        philosopherQuestionTest.new Philosopher1(2).start();
        philosopherQuestionTest.new Philosopher1(3).start();
        philosopherQuestionTest.new Philosopher1(4).start();
    }
 
 
    class Philosopher1 extends Thread {
        private int num;
 
        public Philosopher1(int num) {
            this.num = num;
        }
 
        public void eating() {
            System.out.println("my num is " + num + " , I am eating...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
        public void thinking() {
            System.out.println("my num is " + num + ", I am thinking...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
 
        }
 
        public void takeChopsticks() {
            synchronized (LOCK) {
                int min = Math.min(num, (num + 1) % 5);
                int max = Math.max(num, (num + 1) % 5);
                if (!used[min]) {//先尝试拿小号筷子，失败则进入等待状态，并释放锁
                    used[min] = true;
                    if(!used[max]) {//成功拿到小号筷子后，尝试拿大号筷子，失败，则进入等待状态，并释放锁，但是没有释放小号筷子
                        used[max] = true;
                    } else {
                        try {
                            LOCK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    try {
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
 
        //放下筷子后，通知其他等待线程
        public void putDownChopsticks() {
            synchronized(LOCK) {
                used[num] = false;
                used[(num + 1) % 5] = false;
                System.out.println("my num is " + num + " , I have finished...");
                LOCK.notifyAll();
            }
        }
        
        @Override
        public void run() {
            while(true) {
                thinking();
                takeChopsticks();
                eating();
                putDownChopsticks();
            }
        }
    }
 
}